package org.myspringframework.beans.factory.config;

import org.myspringframework.beans.BeansException;
import org.myspringframework.beans.factory.FactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

//处理关于 FactoryBean 此类对象的注册操作
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

    /**
     * 存放单例类型的factoryBean对象getObject()方法生成的object
     * key:factoryBean的beanName,value:factoryBean的getObject()创建的object
     */
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>();


    protected Object getCachedObjectForFactoryBean(String beanName) {
        Object object = this.factoryBeanObjectCache.get(beanName);
        return (object != NULL_OBJECT ? object : null);
    }

    //获取 FactoryBean#getObject()方法
    protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
        if (factory.isSingleton()) {
            //为单例factroyBean,先从内存缓存中取
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                //缓存中没有这个对象，需要创建
                object = doGetObjectFromFactoryBean(factory, beanName);
                //放入缓存
                this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
            }
            return (object != NULL_OBJECT ? object : null);
        } else {
            //不为单例，重新执行getObject()方法创建新对象
            return doGetObjectFromFactoryBean(factory, beanName);
        }
    }

    private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
        try {
            //执行对象的getObject方法，返回值为bean
            return factory.getObject();
        } catch (Exception e) {
            throw new BeansException("FactoryBean throw exception on object[" + beanName + "] creation", e);
        }
    }

}